package com.yt.order.service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.yt.common.utils.AmapUtils;
import com.yt.common.utils.StrUtils;
import com.yt.order.models.bo.DispatchRuleLogSaveBO;
import com.yt.order.models.dto.DispatchRuleConfigDTO;
import com.yt.order.models.dto.DispatchRuleFilterDTO;
import com.yt.order.models.dto.WorkOrderInfoDTO;
import com.yt.order.models.service.IAutoDispatchService;
import com.yt.order.models.service.IDispatchRuleConfigService;
import com.yt.order.models.service.IDispatchRuleLogService;
import com.yt.order.models.service.IWorkOrderInfoService;
import com.yt.sys.models.dto.EmpAddressDTO;
import com.yt.sys.models.dto.EmpRatingStatsDTO;
import com.yt.sys.models.dto.SysUserDTO;
import com.yt.sys.models.dto.SysUserRoleDTO;
import com.yt.sys.models.service.IEmpAddressService;
import com.yt.sys.models.service.IEmpRatingStatsService;
import com.yt.sys.models.service.ISysUserRoleService;
import com.yt.sys.models.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.dubbo.rpc.RpcException;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 自动派单服务实现
 * 监听订单创建事件，根据派单规则自动分配订单给合适的接单员
 */
@Slf4j
@DubboService(interfaceClass = IAutoDispatchService.class)
public class AutoDispatchServiceImpl implements IAutoDispatchService {

    // 固定的派单员ID
    private static final Long FIXED_DISPATCHER_ID = 1076621663531040768L;
    
    // Redis中已处理订单的key前缀
    private static final String PROCESSED_ORDER_KEY_PREFIX = "auto_dispatch:processed_order:";
    
    // Redis中订单与已分配员工关系的key前缀
    private static final String ORDER_ASSIGNED_EMPLOYEE_KEY_PREFIX = "auto_dispatch:order_assigned_employee:";
    
    // 订单处理记录的过期时间（24小时）
    private static final long PROCESSED_ORDER_EXPIRE_HOURS = 24L;

    @DubboReference
    private IDispatchRuleConfigService dispatchRuleConfigService;

    @DubboReference
    private IWorkOrderInfoService workOrderInfoService;
    
    @DubboReference(check = false)
    private ISysUserService sysUserService;
    
    @DubboReference(check = false)
    private ISysUserRoleService sysUserRoleService;
    
    @DubboReference(check = false)
    private IEmpRatingStatsService empRatingStatsService;
    
    @DubboReference(check = false)
    private IEmpAddressService empAddressService;
    
    // 引用日志服务接口
    @DubboReference
    private com.yt.order.models.service.IDispatchRuleLogService dispatchRuleLogService;
    
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 获取工单信息服务实例
     * @return 工单信息服务实例
     */
    public IWorkOrderInfoService getWorkOrderInfoService() {
        return workOrderInfoService;
    }

    /**
     * 监听订单创建事件，触发自动派单流程
     *
     * @param orderId 新创建的订单ID
     */
    @Async
    @Override
    public void handleOrderCreated(Long orderId) {
        try {
            log.info("开始处理订单自动分配，订单ID: {}", orderId);
            
            // 检查订单是否已经处理过
            String processedOrderKey = PROCESSED_ORDER_KEY_PREFIX + orderId;
            if (Boolean.TRUE.equals(redisTemplate.hasKey(processedOrderKey))) {
                log.info("订单ID: {} 已经处理过，跳过自动分配", orderId);
                return;
            }

            // 获取订单信息
            WorkOrderInfoDTO order = workOrderInfoService.selectById(orderId);
            if (order == null) {
                log.warn("订单不存在，ID: {}", orderId);
                // 标记为已处理防止重复查询
                redisTemplate.opsForValue().set(processedOrderKey, "not_found", PROCESSED_ORDER_EXPIRE_HOURS, TimeUnit.HOURS);
                return;
            }

            // 检查订单状态，只有待分配的订单才需要自动分配
            if (order.getStatus() != null && order.getStatus() != 0) {
                log.info("订单状态不是待分配，不需要自动分配，订单ID: {}, 状态: {}", orderId, order.getStatus());
                // 标记为已处理
                redisTemplate.opsForValue().set(processedOrderKey, "not_eligible", PROCESSED_ORDER_EXPIRE_HOURS, TimeUnit.HOURS);
                return;
            }

            // 获取所有启用的派单规则
            Wrapper<DispatchRuleConfigDTO> ruleWrapper = new EntityWrapper<>();
            ruleWrapper.eq("status", 1); // 只获取启用的规则
            List<DispatchRuleConfigDTO> rules = dispatchRuleConfigService.selectList(ruleWrapper);

            // 根据订单类型过滤并按优先级排序规则
            List<DispatchRuleConfigDTO> matchedRules = rules.stream()
                    .filter(rule -> Objects.equals(rule.getType(), order.getType()))
                    .sorted(Comparator.comparing(DispatchRuleConfigDTO::getPriority))
                    .collect(Collectors.toList());

            log.info("找到 {} 个匹配的派单规则用于订单ID: {}", matchedRules.size(), orderId);

            boolean assigned = false;
            // 遍历规则，尝试为订单分配接单员
            for (DispatchRuleConfigDTO rule : matchedRules) {
                if (tryAssignOrderWithRule(order, rule)) {
                    log.info("成功为订单ID: {} 分配接单员，使用规则ID: {}", orderId, rule.getId());
                    assigned = true;
                    break; // 分配成功则退出循环
                }
            }
            
            // 无论分配成功还是失败，都标记为已处理
            String result = assigned ? "assigned" : "failed";
            redisTemplate.opsForValue().set(processedOrderKey, result, PROCESSED_ORDER_EXPIRE_HOURS, TimeUnit.HOURS);
            
        } catch (Exception e) {
            log.error("处理订单自动分配时发生异常，订单ID: {}", orderId, e);
            // 发生异常时也标记为已处理，防止重复尝试
            String processedOrderKey = PROCESSED_ORDER_KEY_PREFIX + orderId;
            redisTemplate.opsForValue().set(processedOrderKey, "error", PROCESSED_ORDER_EXPIRE_HOURS, TimeUnit.HOURS);
        }
    }

    /**
     * 尝试使用指定规则为订单分配接单员
     *
     * @param order 订单信息
     * @param rule  派单规则
     * @return 是否分配成功
     */
    private boolean tryAssignOrderWithRule(WorkOrderInfoDTO order, DispatchRuleConfigDTO rule) {
        DispatchRuleLogSaveBO logDTO = new DispatchRuleLogSaveBO();
        logDTO.setOrderId(order.getId());
        logDTO.setRuleId(rule.getId());
        logDTO.setRuleName(rule.getRuleName());
        logDTO.setExecuteTime(new Date());
        
        try {
            log.info("开始使用规则ID: {} 为订单ID: {} 分配接单员", rule.getId(), order.getId());

            // 获取规则的过滤条件
            List<DispatchRuleFilterDTO> filters = dispatchRuleConfigService.selectFiltersByRuleId(rule.getId());
            
            log.info("规则ID: {} 包含 {} 个过滤条件", rule.getId(), filters.size());
            
            // 构建过滤详细过程信息
            StringBuilder filterDetails = new StringBuilder();
            filterDetails.append("规则ID: ").append(rule.getId()).append(", 规则名称: ").append(rule.getRuleName()).append("\n");
            filterDetails.append("过滤条件数量: ").append(filters.size()).append("\n");
            for (int i = 0; i < filters.size(); i++) {
                DispatchRuleFilterDTO filter = filters.get(i);
                filterDetails.append("条件").append(i + 1).append(": 类型=")
                    .append(filter.getFilterType()).append(", 操作符=")
                    .append(filter.getOperator()).append(", 值=")
                    .append(filter.getFilterVal()).append("\n");
            }

            // 获取所有可接单的员工列表
            List<EmployeeInfo> employees = getAllAvailableEmployees();
            
            log.info("系统中有 {} 个可接单员工", employees.size());
            
            // 记录初始员工数量
            logDTO.setEmpCount(employees.size());
            
            // 排除已经成功分配过该订单的员工
            List<EmployeeInfo> filteredEmployeesExcludeAssigned = excludePreviouslyAssignedEmployees(employees, order.getId());
            log.info("排除已分配员工后剩余 {} 个员工", filteredEmployeesExcludeAssigned.size());

            // 根据过滤条件筛选员工
            List<EmployeeInfo> filteredEmployees = filterEmployees(filteredEmployeesExcludeAssigned, filters, order);
            
            log.info("根据过滤条件筛选后剩余 {} 个符合条件的员工", filteredEmployees.size());
            
            // 记录筛选后员工数量
            logDTO.setEmpCountFilter(filteredEmployees.size());
            
            // 记录过滤详细过程
            logDTO.setFilterDetails(filterDetails.toString());

            // 根据规则的匹配模式对员工进行排序
            List<EmployeeInfo> sortedEmployees = sortEmployeesByMatchMode(filteredEmployees, rule.getMatchMode(), order);
            
            log.info("根据匹配模式排序后员工数量: {}", sortedEmployees.size());

            // 如果有符合条件的员工，则选择第一个进行分配
            if (!sortedEmployees.isEmpty()) {
                EmployeeInfo assignedEmployee = sortedEmployees.get(0);
                
                // 执行分配操作，使用固定的派单员ID
                boolean assigned = workOrderInfoService.assignOrder(order.getId(), FIXED_DISPATCHER_ID, assignedEmployee.getId());
                
                if (assigned) {
                    log.info("成功将订单ID: {} 分配给员工ID: {}，派单员ID: {}", order.getId(), assignedEmployee.getId(), FIXED_DISPATCHER_ID);
                    logDTO.setExecuteResult("成功分配给员工ID: " + assignedEmployee.getId() + "，派单员ID: " + FIXED_DISPATCHER_ID);
                    
                    // 记录订单与员工的分配关系
                    recordOrderEmployeeAssignment(order.getId(), assignedEmployee.getId());
                    
                    // 只有在分配成功时才记录日志
                    dispatchRuleLogService.add(logDTO);
                    return true;
                } else {
                    log.error("订单分配失败，订单ID: {}, 员工ID: {}，派单员ID: {}", order.getId(), assignedEmployee.getId(), FIXED_DISPATCHER_ID);
                    logDTO.setExecuteResult("订单分配失败，员工ID: " + assignedEmployee.getId() + "，派单员ID: " + FIXED_DISPATCHER_ID);
                }
            } else {
                log.info("没有找到符合条件的员工用于订单ID: {}，使用规则ID: {}", order.getId(), rule.getId());
                logDTO.setExecuteResult("没有找到符合条件的员工");
            }
        } catch (Exception e) {
            log.error("使用规则ID: {} 为订单ID: {} 分配接单员时发生异常", rule.getId(), order.getId(), e);
            logDTO.setExecuteResult("执行异常: " + e.getMessage());
        }
        
        // 不再记录分配失败的日志
        return false;
    }

    /**
     * 排除已经成功分配过该订单的员工
     *
     * @param employees 员工列表
     * @param orderId 订单ID
     * @return 过滤后的员工列表
     */
    private List<EmployeeInfo> excludePreviouslyAssignedEmployees(List<EmployeeInfo> employees, Long orderId) {
        String assignedEmployeeKey = ORDER_ASSIGNED_EMPLOYEE_KEY_PREFIX + orderId;
        if (Boolean.FALSE.equals(redisTemplate.hasKey(assignedEmployeeKey))) {
            // 如果没有记录过分配信息，直接返回所有员工
            return employees;
        }
        
        // 获取已经分配过该订单的员工ID列表
        Set<Object> assignedEmployeeIds = redisTemplate.opsForSet().members(assignedEmployeeKey);
        if (assignedEmployeeIds == null || assignedEmployeeIds.isEmpty()) {
            return employees;
        }
        
        // 过滤掉已经分配过的员工
        return employees.stream()
                .filter(employee -> !assignedEmployeeIds.contains(employee.getId()))
                .collect(Collectors.toList());
    }

    /**
     * 记录订单与员工的分配关系
     *
     * @param orderId 订单ID
     * @param employeeId 员工ID
     */
    private void recordOrderEmployeeAssignment(Long orderId, Long employeeId) {
        String assignedEmployeeKey = ORDER_ASSIGNED_EMPLOYEE_KEY_PREFIX + orderId;
        redisTemplate.opsForSet().add(assignedEmployeeKey, employeeId);
        redisTemplate.expire(assignedEmployeeKey, PROCESSED_ORDER_EXPIRE_HOURS, TimeUnit.HOURS);
    }

    /**
     * 根据过滤条件筛选员工
     *
     * @param employees 员工列表
     * @param filters   过滤条件
     * @param order     订单信息
     * @return 筛选后的员工列表
     */
    private List<EmployeeInfo> filterEmployees(List<EmployeeInfo> employees, List<DispatchRuleFilterDTO> filters, WorkOrderInfoDTO order) {
        List<EmployeeInfo> result = new ArrayList<>(employees);
        
        // 按照排序字段对过滤条件进行排序
        filters.sort(Comparator.comparing(DispatchRuleFilterDTO::getSort));
        
        // 依次应用每个过滤条件
        for (DispatchRuleFilterDTO filter : filters) {
            result = applyFilter(result, filter, order);
            log.info("应用过滤条件后剩余 {} 个员工，过滤条件类型: {}", result.size(), filter.getFilterType());
            
            // 如果没有员工满足条件，则提前结束
            if (result.isEmpty()) {
                break;
            }
        }
        
        return result;
    }

    /**
     * 应用单个过滤条件
     *
     * @param employees 员工列表
     * @param filter    过滤条件
     * @param order     订单信息
     * @return 筛选后的员工列表
     */
    private List<EmployeeInfo> applyFilter(List<EmployeeInfo> employees, DispatchRuleFilterDTO filter, WorkOrderInfoDTO order) {
        switch (filter.getFilterType()) {
            case 0: // 员工星级
                return filterByStarRating(employees, filter);
            case 1: // 员工单量
                return filterByOrderCount(employees, filter);
            case 2: // 员工位置信息和订单的位置信息的距离
                return filterByDistance(employees, filter, order);
            default:
                log.warn("未知的过滤条件类型: {}", filter.getFilterType());
                return employees;
        }
    }

    /**
     * 根据员工星级筛选
     *
     * @param employees 员工列表
     * @param filter    过滤条件
     * @return 筛选后的员工列表
     */
    private List<EmployeeInfo> filterByStarRating(List<EmployeeInfo> employees, DispatchRuleFilterDTO filter) {
        try {
            BigDecimal threshold = new BigDecimal(filter.getFilterVal());
            switch (filter.getOperator()) {
                case ">":
                    return employees.stream()
                            .filter(emp -> emp.getStarRating() != null && emp.getStarRating().compareTo(threshold) > 0)
                            .collect(Collectors.toList());
                case ">=":
                    return employees.stream()
                            .filter(emp -> emp.getStarRating() != null && emp.getStarRating().compareTo(threshold) >= 0)
                            .collect(Collectors.toList());
                case "<":
                    return employees.stream()
                            .filter(emp -> emp.getStarRating() != null && emp.getStarRating().compareTo(threshold) < 0)
                            .collect(Collectors.toList());
                case "<=":
                    return employees.stream()
                            .filter(emp -> emp.getStarRating() != null && emp.getStarRating().compareTo(threshold) <= 0)
                            .collect(Collectors.toList());
                case "=":
                    return employees.stream()
                            .filter(emp -> emp.getStarRating() != null && emp.getStarRating().compareTo(threshold) == 0)
                            .collect(Collectors.toList());
                case "!=":
                    return employees.stream()
                            .filter(emp -> emp.getStarRating() != null && emp.getStarRating().compareTo(threshold) != 0)
                            .collect(Collectors.toList());
                default:
                    log.warn("未知的比较操作符: {}", filter.getOperator());
                    return employees;
            }
        } catch (NumberFormatException e) {
            log.error("解析星级阈值失败，阈值: {}", filter.getFilterVal(), e);
            return employees;
        }
    }

    /**
     * 根据员工单量筛选
     *
     * @param employees 员工列表
     * @param filter    过滤条件
     * @return 筛选后的员工列表
     */
    private List<EmployeeInfo> filterByOrderCount(List<EmployeeInfo> employees, DispatchRuleFilterDTO filter) {
        try {
            Integer threshold = Integer.valueOf(filter.getFilterVal());
            switch (filter.getOperator()) {
                case ">":
                    return employees.stream()
                            .filter(emp -> emp.getOrderCount() != null && emp.getOrderCount() > threshold)
                            .collect(Collectors.toList());
                case ">=":
                    return employees.stream()
                            .filter(emp -> emp.getOrderCount() != null && emp.getOrderCount() >= threshold)
                            .collect(Collectors.toList());
                case "<":
                    return employees.stream()
                            .filter(emp -> emp.getOrderCount() != null && emp.getOrderCount() < threshold)
                            .collect(Collectors.toList());
                case "<=":
                    return employees.stream()
                            .filter(emp -> emp.getOrderCount() != null && emp.getOrderCount() <= threshold)
                            .collect(Collectors.toList());
                case "=":
                    return employees.stream()
                            .filter(emp -> emp.getOrderCount() != null && emp.getOrderCount().equals(threshold))
                            .collect(Collectors.toList());
                case "!=":
                    return employees.stream()
                            .filter(emp -> emp.getOrderCount() != null && !emp.getOrderCount().equals(threshold))
                            .collect(Collectors.toList());
                default:
                    log.warn("未知的比较操作符: {}", filter.getOperator());
                    return employees;
            }
        } catch (NumberFormatException e) {
            log.error("解析单量阈值失败，阈值: {}", filter.getFilterVal(), e);
            return employees;
        }
    }

    /**
     * 根据员工位置和订单位置的距离筛选
     *
     * @param employees 员工列表
     * @param filter    过滤条件
     * @param order     订单信息
     * @return 筛选后的员工列表
     */
    private List<EmployeeInfo> filterByDistance(List<EmployeeInfo> employees, DispatchRuleFilterDTO filter, WorkOrderInfoDTO order) {
        try {
            BigDecimal threshold = new BigDecimal(filter.getFilterVal());
            switch (filter.getOperator()) {
                case ">":
                    return employees.stream()
                            .filter(emp -> calculateDistance(emp, order) != null && calculateDistance(emp, order).compareTo(threshold) > 0)
                            .collect(Collectors.toList());
                case ">=":
                    return employees.stream()
                            .filter(emp -> calculateDistance(emp, order) != null && calculateDistance(emp, order).compareTo(threshold) >= 0)
                            .collect(Collectors.toList());
                case "<":
                    return employees.stream()
                            .filter(emp -> calculateDistance(emp, order) != null && calculateDistance(emp, order).compareTo(threshold) < 0)
                            .collect(Collectors.toList());
                case "<=":
                    return employees.stream()
                            .filter(emp -> calculateDistance(emp, order) != null && calculateDistance(emp, order).compareTo(threshold) <= 0)
                            .collect(Collectors.toList());
                case "=":
                    return employees.stream()
                            .filter(emp -> calculateDistance(emp, order) != null && calculateDistance(emp, order).compareTo(threshold) == 0)
                            .collect(Collectors.toList());
                case "!=":
                    return employees.stream()
                            .filter(emp -> calculateDistance(emp, order) != null && calculateDistance(emp, order).compareTo(threshold) != 0)
                            .collect(Collectors.toList());
                default:
                    log.warn("未知的比较操作符: {}", filter.getOperator());
                    return employees;
            }
        } catch (NumberFormatException e) {
            log.error("解析距离阈值失败，阈值: {}", filter.getFilterVal(), e);
            return employees;
        }
    }

    /**
     * 计算员工与订单之间的距离
     *
     * @param employee 员工信息
     * @param order    订单信息
     * @return 距离（公里）
     */
    private BigDecimal calculateDistance(EmployeeInfo employee, WorkOrderInfoDTO order) {
        // 获取员工位置信息
        if (employee.getLongitude() == null || employee.getLatitude() == null) {
            log.warn("员工ID: {} 没有位置信息", employee.getId());
            return null;
        }
        
        // 获取订单位置信息
        BigDecimal[] orderCoordinates = getOrderCoordinates(order);
        if (orderCoordinates == null) {
            log.warn("无法获取订单ID: {} 的位置信息", order.getId());
            return null;
        }
        
        BigDecimal orderLongitude = orderCoordinates[0];
        BigDecimal orderLatitude = orderCoordinates[1];
        
        // 使用Haversine公式计算距离
        return calculateDistance(
                employee.getLatitude(), employee.getLongitude(),
                orderLatitude, orderLongitude);
    }
    
    /**
     * 获取订单的经纬度坐标
     * 
     * @param order 订单信息
     * @return 经纬度坐标数组，[0]为经度，[1]为纬度
     */
    private BigDecimal[] getOrderCoordinates(WorkOrderInfoDTO order) {
        // 优先使用订单中的经纬度信息
        if (order.getLongitude() != null && order.getLatitude() != null) {
            log.info("订单ID: {} 直接使用订单中的经纬度信息", order.getId());
            return new BigDecimal[]{order.getLongitude(), order.getLatitude()};
        }
        
        // 检查订单地址是否为空
        if (StrUtils.isEmpty(order.getAddress())) {
            log.warn("订单ID: {} 的地址信息为空", order.getId());
            return null;
        }
        
        // 使用高德地图API获取地址的经纬度坐标
        log.info("订单ID: {} 使用高德地图API解析地址获取经纬度信息", order.getId());
        return AmapUtils.getCoordinatesByAddress(order.getAddress());
    }
    
    /**
     * 使用Haversine公式计算两点之间的距离
     * 
     * @param lat1 第一个点的纬度
     * @param lon1 第一个点的经度
     * @param lat2 第二个点的纬度
     * @param lon2 第二个点的经度
     * @return 距离（公里）
     */
    private BigDecimal calculateDistance(BigDecimal lat1, BigDecimal lon1, BigDecimal lat2, BigDecimal lon2) {
        // 地球半径（公里）
        double R = 6371.0;
        
        // 将角度转换为弧度
        double lat1Rad = Math.toRadians(lat1.doubleValue());
        double lon1Rad = Math.toRadians(lon1.doubleValue());
        double lat2Rad = Math.toRadians(lat2.doubleValue());
        double lon2Rad = Math.toRadians(lon2.doubleValue());
        
        // 计算差值
        double deltaLat = lat2Rad - lat1Rad;
        double deltaLon = lon2Rad - lon1Rad;
        
        // Haversine公式
        double a = Math.pow(Math.sin(deltaLat / 2), 2) +
                   Math.cos(lat1Rad) * Math.cos(lat2Rad) *
                   Math.pow(Math.sin(deltaLon / 2), 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        
        // 计算距离
        double distance = R * c;
        
        return new BigDecimal(distance).setScale(2, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 根据规则的匹配模式对员工进行排序
     *
     * @param employees  员工列表
     * @param matchMode  匹配模式 (0距离优先，1星级优先，2单量优先)
     * @param order      订单信息
     * @return 排序后的员工列表
     */
    private List<EmployeeInfo> sortEmployeesByMatchMode(List<EmployeeInfo> employees, Integer matchMode, WorkOrderInfoDTO order) {
        if (employees == null || employees.isEmpty()) {
            return employees;
        }

        switch (matchMode != null ? matchMode : 0) {
            case 0: // 距离优先
                return employees.stream()
                        .sorted(Comparator.comparing(emp -> calculateDistance(emp, order), Comparator.nullsLast(BigDecimal::compareTo)))
                        .collect(Collectors.toList());
                
            case 1: // 星级优先
                return employees.stream()
                        .sorted(Comparator.comparing(EmployeeInfo::getStarRating, Comparator.nullsLast(Comparator.reverseOrder())))
                        .collect(Collectors.toList());
                
            case 2: // 单量优先
                return employees.stream()
                        .sorted(Comparator.comparing(EmployeeInfo::getOrderCount, Comparator.nullsLast(Comparator.reverseOrder())))
                        .collect(Collectors.toList());
                
            default:
                log.warn("未知的匹配模式: {}，使用默认排序", matchMode);
                return employees;
        }
    }

    /**
     * 获取所有可接单的员工列表
     *
     * @return 员工列表
     */
    private List<EmployeeInfo> getAllAvailableEmployees() {
        List<EmployeeInfo> employees = new ArrayList<>();
        
        try {
            // 获取所有在职员工
            Wrapper<SysUserDTO> userWrapper = new EntityWrapper<>();
            userWrapper.eq("status", 1); // 1表示在职
            List<SysUserDTO> sysUsers = sysUserService.selectList(userWrapper);
            
            if (CollectionUtils.isEmpty(sysUsers)) {
                log.warn("没有找到在职员工");
                return employees;
            }
            
            log.info("找到 {} 个在职员工", sysUsers.size());
            
            // 获取员工ID列表
            List<Long> userIds = sysUsers.stream()
                    .map(SysUserDTO::getId)
                    .collect(Collectors.toList());
            
            // 获取用户角色信息，只筛选角色ID为4的接单员（明确声明接单员是角色ID为4的用户）
            Wrapper<SysUserRoleDTO> userRoleWrapper = new EntityWrapper<>();
            userRoleWrapper.in("user_id", userIds);
            userRoleWrapper.eq("role_id", 4); // 4表示接单员角色
            List<SysUserRoleDTO> userRoles = sysUserRoleService.selectList(userRoleWrapper);
            
            // 获取接单员用户ID列表
            List<Long> orderTakerUserIds = userRoles.stream()
                    .map(SysUserRoleDTO::getUserId)
                    .distinct()
                    .collect(Collectors.toList());
            
            if (CollectionUtils.isEmpty(orderTakerUserIds)) {
                log.warn("没有找到具有接单员角色的员工");
                return employees;
            }
            
            log.info("找到 {} 个具有接单员角色的员工", orderTakerUserIds.size());
            
            // 只保留在职且具有接单员角色的员工
            List<SysUserDTO> orderTakerUsers = sysUsers.stream()
                    .filter(user -> orderTakerUserIds.contains(user.getId()))
                    .collect(Collectors.toList());
            
            // 获取接单员用户ID列表
            List<Long> orderTakerIds = orderTakerUsers.stream()
                    .map(SysUserDTO::getId)
                    .collect(Collectors.toList());
            
            // 批量获取员工星级统计信息
            Wrapper<EmpRatingStatsDTO> ratingWrapper = new EntityWrapper<>();
            ratingWrapper.in("user_id", orderTakerIds);
            List<EmpRatingStatsDTO> ratingStatsList = empRatingStatsService.selectList(ratingWrapper);
            Map<Long, EmpRatingStatsDTO> ratingStatsMap = ratingStatsList.stream()
                    .collect(Collectors.toMap(EmpRatingStatsDTO::getUserId, r -> r));
            
            // 批量获取员工位置信息
            Wrapper<EmpAddressDTO> addressWrapper = new EntityWrapper<>();
            addressWrapper.in("emp_id", orderTakerIds);
            List<EmpAddressDTO> addressList = empAddressService.selectList(addressWrapper);
            Map<Long, EmpAddressDTO> addressMap = addressList.stream()
                    .collect(Collectors.toMap(EmpAddressDTO::getEmpId, a -> a));
            
            // 构建员工信息列表
            for (SysUserDTO sysUser : orderTakerUsers) {
                Long userId = sysUser.getId();
                
                // 获取员工已完成订单数量
                int completedOrders = workOrderInfoService.countCompletedOrdersByEmployeeId(userId);
                
                // 获取员工星级统计
                EmpRatingStatsDTO ratingStats = ratingStatsMap.get(userId);
                BigDecimal starRating = (ratingStats != null) ? ratingStats.getTotalRating() : BigDecimal.ZERO;
                
                // 获取员工位置信息
                EmpAddressDTO address = addressMap.get(userId);
                BigDecimal longitude = (address != null) ? address.getLongitude() : null;
                BigDecimal latitude = (address != null) ? address.getLatitude() : null;
                
                // 创建员工信息对象
                EmployeeInfo employee = new EmployeeInfo(userId, starRating, completedOrders, latitude, longitude);
                employees.add(employee);
            }
        } catch (RpcException e) {
            log.error("获取员工列表时发生RPC异常，请检查sys-service服务是否正常运行且网络连接正常", e);
        } catch (Exception e) {
            log.error("获取员工列表时发生异常", e);
        }
        
        return employees;
    }

    /**
     * 员工信息内部类
     */
    private static class EmployeeInfo {
        private Long id;
        private BigDecimal starRating;
        private Integer orderCount;
        private BigDecimal latitude;
        private BigDecimal longitude;

        public EmployeeInfo(Long id, BigDecimal starRating, Integer orderCount, BigDecimal latitude, BigDecimal longitude) {
            this.id = id;
            this.starRating = starRating;
            this.orderCount = orderCount;
            this.latitude = latitude;
            this.longitude = longitude;
        }

        public Long getId() {
            return id;
        }

        public BigDecimal getStarRating() {
            return starRating;
        }

        public Integer getOrderCount() {
            return orderCount;
        }

        public BigDecimal getLatitude() {
            return latitude;
        }

        public BigDecimal getLongitude() {
            return longitude;
        }
    }
}